package com.orientation.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.orientation.commom.exception.CustomException;
import com.orientation.entity.Permission;
import com.orientation.entity.Role;
import com.orientation.mapper.RoleMapper;
import com.orientation.service.PermissionService;
import com.orientation.service.RoleService;
import com.orientation.vo.RolePermVo;
import com.orientation.vo.RoleSidebarVo;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author xuandian
 * @since 2021-10-11
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Resource
    private PermissionService permissionService;

    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleService roleService;


    @Override
    public List<RolePermVo> findPermById(String id) {
        List<Permission> permissionList = permissionService.list();
        //过滤pid为空情况
        List<Permission> permissionParentList = permissionList.stream().filter(p -> !StringUtils.hasLength(p.getPid())).collect(Collectors.toList());
        Role role = getById(id);

        Map<String, RolePermVo> permDataMap;
        if (StringUtils.hasText(role.getPermission())) {
            try {
                //json字符串转对象 objectMapper是jackson的类，专用来解析json的  =>  最转为map 对象
                permDataMap = objectMapper.readValue(role.getPermission(), new TypeReference<List<RolePermVo>>() {
                }).stream().collect(Collectors.toMap(RolePermVo::getSid, s -> s));
            } catch (JsonProcessingException e) {
                log.error("Json解析失败");
                throw new CustomException("10011", "Json解析失败");
            }
        } else {
            permDataMap = new HashMap<>();
        }
        List<RolePermVo> permVoList = new ArrayList<>();
        for (Permission permission : permissionParentList) {
            RolePermVo rolePermVo = new RolePermVo();
            rolePermVo.setTitle(permission.getName());
            rolePermVo.setSid(permission.getSid());
            if (permDataMap.containsKey(permission.getSid())) {
                RolePermVo permVo = permDataMap.get(permission.getSid());
                rolePermVo.setCheckAll(permVo.getCheckAll());
                rolePermVo.setIsIndeterminate(permVo.getIsIndeterminate());
                rolePermVo.setCheckedList(permVo.getCheckedList());
            } else {
                rolePermVo.setCheckAll(false);
                rolePermVo.setIsIndeterminate(false);
                rolePermVo.setCheckedList(new ArrayList<>());
            }
            // 替换subs里面为最新的权限页面数据
            List<RolePermVo.Sub> subList = new ArrayList<>();
            List<Permission> permissionList1 = permissionList.stream().filter(p -> rolePermVo.getSid().equals(p.getPid())).collect(Collectors.toList());
            for (Permission permissionChild : permissionList1) {
                RolePermVo.Sub sub = new RolePermVo.Sub();
                sub.setSid(permissionChild.getSid());
                sub.setTitle(permissionChild.getName());
                sub.setIndex(permissionChild.getPath());
                subList.add(sub);
            }
            rolePermVo.setSubs(subList);
            permVoList.add(rolePermVo);
        }
        return permVoList;
    }

    @Override
    public List<RoleSidebarVo> findSidebarById(String id) {
        Role role = getById(id);
        List<RoleSidebarVo> sidebarVoList;
        if (StringUtils.hasText(role.getPermission())) {
            try {
                sidebarVoList = objectMapper.readValue(role.getPermission(), new TypeReference<List<RoleSidebarVo>>() {
                }).stream().filter(s -> !s.getCheckedList().isEmpty()).collect(Collectors.toList());
            } catch (JsonProcessingException e) {
                log.error("Json解析失败");
                throw new CustomException("10011", "Json解析失败");
            }
            // 替换subs里面为有权限的页面
            for (RoleSidebarVo rolePermVo : sidebarVoList) {
                List<Permission> permissionList = permissionService.listByIds(rolePermVo.getCheckedList());
                List<RolePermVo.Sub> subList = new ArrayList<>();
                for (Permission permission : permissionList) {
                    RolePermVo.Sub sub = new RolePermVo.Sub();
                    sub.setSid(permission.getSid());
                    sub.setTitle(permission.getName());
                    sub.setIndex(permission.getPath());
                    subList.add(sub);
                }
                rolePermVo.setSubs(subList);
                rolePermVo.setIcon("el-icon-lx-cascades");
                rolePermVo.setIndex(rolePermVo.getSid());
            }
            return sidebarVoList;

        } else {
            sidebarVoList = new ArrayList<>();
        }
        return sidebarVoList;
    }

    @Override
    public boolean updatePermById(String id, String permission) {
        Role role = getById(id);
        if (ObjectUtils.isEmpty(role)) {
            return false;
        }
        role.setPermission(permission);
        updateById(role);
        return true;
    }

    @Override
    public void insertRole(Role role) {
        if (role!= null && StringUtils.hasLength( role.getName())) {
            Role selectOne = roleMapper.selectOne(Wrappers.<Role>lambdaQuery().eq(Role::getName, role.getName()).groupBy(Role::getName));
            if (selectOne != null) {
                throw new CustomException("18","此角色已经存在,请勿重复添加");
            }
            else {
                save(role);
            }
        }
    }
}
